package Buildings.net.server.parallel;
import Buildings.*;
import Buildings.dwelling.*;
import Buildings.office.*;
import Buildings.dwelling.hotel.*;
import Errors.*;
import Interfaces.*;
import java.io.*;
import java.net.*;
//import java.util.Random;

public class BinaryServerParallel {
    private static class ServerThread extends Thread{
        private Socket c;
        private DataInputStream in;
        private DataOutputStream out;
        private static String []mass=new String[]{"Dwelling","Office","Hotel"};
        private static double getCash(Building b)throws BuildingUnderArrestException{
        int value=(int)(Math.random()*10);
//        Random arest=new Random();
//        int value=arest.nextInt(10);
        if(value==1) throw new BuildingUnderArrestException();
        double s=0;
        int m[]=new int[]{1};
        Dwelling d=new Dwelling(1,m);
        OfficeBuilding o=new OfficeBuilding(1,m);
        Hotel h=new Hotel(1,m);
        if(b.getClass()==d.getClass()){
            s=b.getHowMuchAreaInBuilding()*1000;
        }
        if(b.getClass()==o.getClass()){
            s=b.getHowMuchAreaInBuilding()*1500;
        }
        if(b.getClass()==h.getClass()){
            s=b.getHowMuchAreaInBuilding()*2000;
        }
        return s;
    }
        private static void getProcess(String type, DataInputStream in,DataOutputStream out)throws IOException,BuildingUnderArrestException{
        if(type.equalsIgnoreCase(mass[0])){
            System.out.println("Считан Dwelling");
            Buildings.setBuildingFactory(new DwellingFactory());
        }else if(type.equalsIgnoreCase(mass[1])){
            System.out.println("Считан Office");
            Buildings.setBuildingFactory(new OfficeFactory());
        }else if(type.equalsIgnoreCase(mass[2])){
            System.out.println("Считан Hotel");
            Buildings.setBuildingFactory(new HotelFactory());
        }else return;
        String cashS;//цена в строке
        byte []cashB;//цена в массиве битов
        int sx;//размерность массива битов
        double cash=0;//цена в формате число
        Building b; //экземпляр здания для подсчета
        String buildS; //здание в строке
        sx=in.read();
        byte []buildB=new byte[sx];
        in.read(buildB);
        buildS=new String(buildB, "cp1251");
        StringReader s=new StringReader(buildS);
        b=Buildings.readBuilding(s);
        cash=getCash(b);
        cashS=Double.toString(cash);
        cashB=cashS.getBytes();
        out.write(cashB.length);
        out.write(cashB);
        System.out.println("Записано "+cash);  
        return;
    }
        public void run(){
            try{
                in=new DataInputStream(c.getInputStream());
                out=new DataOutputStream(c.getOutputStream());
            }catch(IOException CantCreateServerChanel){
                System.out.println("Ошибка создания потока сервера!");
                System.exit(1);
            }
            
            String typeS=null;//тип здания в строке
            byte []typeB;//тип здания в массиве битов
            int sx;//размерность массива
  
            try{
                sx=in.read();
                typeB=new byte[sx];
                in.read(typeB);
                typeS=new String(typeB, "cp1251");
                while(typeS.equalsIgnoreCase("END")==false){
                    try{
                        getProcess(typeS,in,out);
                    
                    }catch(BuildingUnderArrestException Arest){
                        out.write("Arest".getBytes().length);
                        out.write("Arest".getBytes());
                        System.out.println("Arest");
                    }catch(IOException IOSocket){
                        System.out.println("Ошибка чтения-записи в сокет");
                        System.exit(1);
                    }
                    //считываем следующий тип здания
                    sx=in.read();
                    typeB=new byte[sx];
                    in.read(typeB);
                    typeS=new String(typeB, "cp1251");
                }
                System.out.println("Считан конец");
            }catch(IOException SynchroReader){
                System.out.println("Невозможно прочитать синхро метку");
                System.exit(1);
            }
        
            try{ 
                out.close();
                in.close();
                c.close();
            }catch (IOException ex){
                System.out.println("Ошибка закрытия сокетов и потоков данных");
            } 
        }
        public ServerThread(Socket c){
            super("ServerThread");
            this.c=c;
            start();
        }
    }
    private static final int port=4446;
    public static void main(String arg[]){
        System.out.println("Многопточное серверное приложение - бинарный");
        ServerSocket ss=null;
        try{
            ss=new ServerSocket(port);
        }catch(IOException CantCreateServer){
                System.out.println("Ошибка сервера по протоколу!");
                System.exit(1);
        }
        while(true){
            try{
                Socket client=ss.accept();
                new ServerThread(client);
            }catch(IOException CantCreateServer){
                System.out.println("Ошибка создания потока сервера!");
                System.exit(1);
            }
        }
        
    }
}
